layui.define(
  [
    'table',
    'layer',
    'form',
    'jquery',
    'helper',
    'ax',
    'laytpl',
    'view'
  ],
  function (exports) {

    "use strict";

    var table = layui.table,
      form = layui.form,
      $ = layui.jquery,
      layer = layui.layer,
      helper = layui.helper,
      $ax = layui.ax,
      laytpl = layui.laytpl,
      LAY_YII = {},
      thisPager = function () {

        // 渲染表格组件
        this.renderTable(this.config.table);

        // 渲染行内编辑
        this.renderEditor(this.config.editor);

        // 渲染tools
        this.renderTool();

        // 渲染toolbar
        this.renderToolbar();

        // 监听服务端排序
        if (this.config.sort === 'server') {
          this.config.table.autoSort = false;
          this.reloadSort();
        }

      },

      // 构造器
      Class = function (options, events) {
        this.config = $.extend(this.config, options || {})
        this.events = $.extend(this.events, events || {})
      };

    // 默认配置
    Class.prototype.config = {
      _csrf: '',
      searchModelName: '',
      searchModelClass: '',
      modelClass: '',
      searchFilter: null,
      tableId: '',
      tableFilter: '',
      countCache: false,
      inst: {},
      table: {}, // table 配置
      editor: {}, // 行内编辑
      eventOptions: {}
    };

    Class.prototype.events = {
      create: function (obj, config, that) {
        var helper = layui.helper
            , view = layui.view

        if (!helper.hasKey(config, 'url')) {
          layer.alert('请先配置create请求地址');
          return false
        }

        var condition = helper.getValue(config, 'condition', {})
            , params = helper.getCondition(condition, obj.data)
            , type = helper.getValue(config, 'open', 'iframe')
            , label = helper.getValue(config, 'label', '新建');

        if (type === 'iframe') {
          var winConfig = {title: label, content: config.url + '?iframe=1&' + helper.urlEncode(params)};
          helper.hasKeyFnt(config, 'openRefresh', function (O, K) {
            winConfig.end = function (index, layero) {
              that.reloadTable(null, null)
            }
          });
          view.openIframe(winConfig)
        }
      }
      , edit: function (obj, config, that) {
        var helper = layui.helper
            , view = layui.view

        if (!helper.hasKey(config, 'url')) {
          layer.alert('请先配置update请求地址');
          return false
        }

        var condition = helper.getValue(config, 'condition', {id: ':id'})
            , params = helper.getCondition(condition, obj.data)
            , type = helper.getValue(config, 'open', 'iframe')
            , label = helper.getValue(config, 'label', '更新');

        if (type === 'iframe') {
          var winConfig = {title: label, content: config.url + '?iframe=1&' + helper.urlEncode(params)};
          helper.hasKeyFnt(config, 'openRefresh', function (O, K) {
            winConfig.end = function (index, layero) {
              that.reloadTable(null, null)
            }
          });
          view.openIframe(winConfig)
        }
      }
      , detail: function (obj, config, that) {
        var helper = layui.helper
            , view = layui.view

        if (!helper.hasKey(config, 'url')) {
          layer.alert('请先配置view请求地址');
          return false
        }

        var type = helper.getValue(config, 'open', 'page')
            , label = helper.getValue(config, 'label', '查看')

        if (type === 'page') {
          var condition = helper.getValue(config, 'condition', {id: ':id'})
              , ajax = new $ax(config.url);

          ajax.setMethod('get');
          ajax.setOption('success', function (html) {
            view.openPage({title: label, content: html});
            layer.close(ajax.antIndex);
          });
          ajax.setData(helper.getCondition(condition, obj.data));
          ajax.send();
        }

        if (type === 'iframe') {
          view.openIframe({title: label, content: config.url});
        }

      }
      , del: function (obj, config, that) {
        var helper = layui.helper
        if (!helper.hasKey(config, 'url')) {
          layer.alert('请先配置delete请求地址');
          return false
        }

        var condition = helper.getValue(config, 'condition', {id: ':id'})
            , message = helper.getValue(config, 'message', '确定删除该项目？')
            , params = helper.getCondition(condition, obj.data)

        layer.alert(message, function (index) {
          var ajax = new $ax(config.url + '?' + helper.urlEncode(params));
          ajax.setDataValue('_csrf', that.config._csrf);
          ajax.setMethod('post');
          ajax.setResult(function (result) {
            that.reloadTable(null, null, true);
            layer.close(index);
          });
          ajax.send();
        })

      }
      , deleteBatch: function (obj, config, that) {
        var helper = layui.helper;
        if (!helper.hasKey(config, 'url')) {
          layer.alert('请先配置Batch Delete请求地址');
          return false;
        }

        var table = layui.table
            , checkStatus = table.checkStatus(that.config.tableId)

        if (checkStatus.data.length <= 0) {
          layer.msg('请先选择要操作的数据!')
          return false;
        }

        var condition = helper.getValue(config, 'condition', {'ids': 'id'})
            , message = helper.getValue(config, 'message', '确定删除该项目？')
            , ajax = new $ax(config.url);

        $.each(condition, function (k, v) {
          var d = [];
          $.each(checkStatus.data, function (key, item) {
            d.push(item[v])
          });
          ajax.setDataDataValue(k, d);
        });

        ajax.setDataValue('_csrf', that.config._csrf);
        layer.alert(message, function (index) {
          ajax.setResult(function (res) {
            that.reloadTable(null, null, true);
            layer.close(index)
          });
          ajax.setMethod('post');
          ajax.send();
        });

      }
      , OUTPUT_EXCEL: function (obj, config, that) {
        var helper = layui.helper;
        if (!helper.hasKey(config, 'url')) {
          layer.alert('请先配置OUTPUT_EXCEL请求地址');
          return false;
        }

        var tableIns = that.config.inst['table']
            , filename = helper.getValue(config, 'filename', '导出接口数据')

        var ajax = new $ax(config.url, function (res) {
          res.data.unshift(res.header)
          layui.use(['excel'], function () {
            var excel = layui.excel;
            excel.exportExcel({sheet1: res.data}, filename + '.xlsx', 'xlsx')
          })
        });

        ajax.setMethod(config.method);
        ajax.setData(tableIns.config.where);
        ajax.setHeadersValue('Search-Class', that.config.searchModelClass);
        ajax.send();

      }
    }

    /**
     * 生成table组件
     * @param options
     */
    Class.prototype.renderTable = function (options) {

      var that = this, config = new helper.getTableConfig();

      helper.hasKeyFnt(options, 'url', function (O, K) {
        config.setHeader('Search-Class', that.config.searchModelClass)
      });

      if (that.config.searchFilter != null) {
        config.setConditions($.extend(options['defaultCondition'], form.val(that.config.searchFilter)));

        // 渲染搜索组件
        form.on('submit(' + that.config.searchFilter + ')', function (data) {
          that.reloadTable(null, 1);
          return false;
        })
      }

      if (helper.hasKey(options, 'page')) {
        helper.hasKeyFnt(options['page'], 'hash', function (page, hash) {
          config.setPage('curr', location.hash.replace('#!' + page[hash] + '=', ''));
          config.setPage('hash', page[hash]);
        });
      }

      // 开启count缓存
      if (this.config.countCache) {
        config.setHeader('Cancel-Count', -1);
        config.setProperty('done', function (res, curr, count) {
          this.headers['Cancel-Count'] = count
        })
      }

      // 渲染table 组件
      this.config.inst['table'] = table.render($.extend(options, config));
    };

    /**
     * 刷新table组件
     */
    Class.prototype.reloadTable = function (order, resetPage, resetCount) {

      var config = new helper.getTableConfig(),
        tableIns = this.config.inst['table'],
        options = this.config;

      helper.hasKeyFnt(options.table, 'url', function (O, K) {
        if (order === null) config.setHeader('Search-Class', options.searchModelClass)
      });

      if (options.searchFilter != null) {
        config.setConditions($.extend(options.table['defaultConditions'], form.val(options.searchFilter)));
      }


      if (order instanceof Object) {
        tableIns.config.where.Sort = {}
        config.setProperty('initSort', order);
        config.setSortValue(order.field, order.type);
      }

      if (helper.hasKey(options, 'page')) {
        helper.hasKeyFnt(options['page'], 'hash', function (page, hash) {
          if (resetPage instanceof Number) config.setPage('curr', resetPage);
        });
      }

      if (resetCount === true) {
        config.setHeader('Cancel-Count', -1);
      }

      this.config.inst['table'] = table.reload(options.tableId, config);

    };

    /**
     * 重新渲染排序
     */
    Class.prototype.reloadSort = function () {
      var that = this;
      table.on('sort(' + that.config.tableFilter + ')', function (order) {
        that.reloadTable(order)
      });
    };

    /**
     * 渲染行内编辑
     * @param options
     * @returns {boolean}
     */
    Class.prototype.renderEditor = function (options) {

      if (helper.emptyKey(options, 'url')) {
        return false
      }

      var that = this;
      table.on('edit(' + this.config.tableFilter + ')', function (obj) {
        var message = helper.getValue(options, 'message', '确定修改？');
        layer.alert(message, function (index) {
          var ajax = new $ax(options.url, function (res) {
            layer.msg('修改信息成功！')
          });
          ajax.setMethod(options.method);
          ajax.setHeadersValue('Model-Class', that.config.modelClass);
          ajax.setDataDataValue(obj.field, obj.value);
          var condition = helper.getValue(options, 'condition', {'id': ':id'});
          ajax.setDataCondition(helper.getCondition(condition, obj.data));
          ajax.send();
          layer.close(index)
        })
      });

    };

    /**
     * 渲染tool
     */
    Class.prototype.renderTool = function () {
      var that = this;
      table.on('tool(' + this.config.tableFilter + ')', function (obj) {

        var edit = $(this).attr('data-edit')
          , config = helper.getValue(that.config.eventOptions, obj.event, {});



        if (edit === 'dropdown') {
          that.dropdown(obj, config, that)
          return;
        }

        if (edit === 'radio') {
          that.radio(obj, config, that)
          return;
        }

        that.events[obj.event] && that.events[obj.event].call(this, obj, config, that)
      })
    };

    Class.prototype.dropdown = function (obj, config, that) {

      if (!helper.hasKey(config, 'url')) {
        layer.alert('请先配置修改请求地址');
        return false
      }

      var label = helper.getValue(config, 'label', '更新');
      // var setter = layui.setter;
      var items = helper.getValue(config, 'items', {});

      var options = [];
      layui.each(items, function (key, item) {
        options.push('<option value="' + key + '">' + item + '</option>')
      })

      var html = '<form class="layui-form" lay-filter="dp">\n' +

        '      <select name="v">\n' +
        options.join(" ") +
        '      </select>\n' +

        '  </form>';

      var index = layer.open({
        title: label
        , content: html
        , skin: 'layer-ext-myskin'
        , success: function () {
          form.render('select');
        },
        yes: function () {
          var val = form.val('dp')
          var ajax = new $ax(config.url, function (res) {
            layer.msg('修改信息成功！')
            var update = {}
            update[config.field] = items[val.v]
            obj.update(update)
            // that.reloadTable(null, null)
          })
            , method = helper.getValue(config, 'method', 'get')
            , modelClass = helper.getValue(config, 'modelClass', that.config.modelClass)

          ajax.setMethod(method);
          ajax.setHeadersValue('Model-Class', modelClass);
          ajax.setDataDataValue(config.field, val.v);
          var condition = helper.getValue(config, 'condition', {'id': ':id'});
          ajax.setDataCondition(helper.getCondition(condition, obj.data));
          ajax.send();
        }
      });


    };

    Class.prototype.radio = function (obj, config, that) {

      if (!helper.hasKey(config, 'url')) {
        layer.alert('请先配置修改请求地址');
        return false
      }

      var label = helper.getValue(config, 'label', '更新');
      // var setter = layui.setter;
      var items = helper.getValue(config, 'items', {});

      var options = [];
      layui.each(items, function (key, item) {
        options.push('<input type="radio" name="v" value="' + key + '" title="' + item + '">')
      })

      var html = '<form class="layui-form" lay-filter="dp">\n' +
        options.join(" ") +
        '  </form>';

      var index = layer.open({
        title: label
        , content: html
        , skin: 'layer-ext-myskin'
        , success: function () {
          form.render('radio');
        },
        yes: function () {
          var val = form.val('dp')
          var ajax = new $ax(config.url, function (res) {
            layer.msg('修改信息成功！')
            var update = {}
            update[config.field] = items[val.v]
            obj.update(update)
            // that.reloadTable(null, null)
          })
            , method = helper.getValue(config, 'method', 'get')
            , modelClass = helper.getValue(config, 'modelClass', that.config.modelClass)

          ajax.setMethod(method);
          ajax.setHeadersValue('Model-Class', modelClass);
          ajax.setDataDataValue(config.field, val.v);
          var condition = helper.getValue(config, 'condition', {'id': ':id'});
          ajax.setDataCondition(helper.getCondition(condition, obj.data));
          ajax.send();
        }
      });


    };

    /**
     * 渲染toolbar
     */
    Class.prototype.renderToolbar = function () {
      var that = this;
      table.on('toolbar(' + that.config.tableFilter + ')', function (obj) {
        var config = helper.getValue(that.config.eventOptions, obj.event, {});
        that.events[obj.event] && that.events[obj.event].call(this, obj, config, that)
      })
    };

    // 核心入口
    LAY_YII.render = function (options, events) {
      var inst = new Class(options, events);
      return thisPager.call(inst);
    };

    exports('grid', LAY_YII)

  });
